package drds.plus.sql_process.abstract_syntax_tree.expression.item.column;

import drds.plus.common.jdbc.Parameters;
import drds.plus.sql_process.abstract_syntax_tree.IExecutePlanVisitor;
import drds.plus.sql_process.abstract_syntax_tree.ObjectCreateFactory;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.Item;
import drds.plus.sql_process.type.Type;
import drds.tools.$;
import lombok.Getter;
import lombok.Setter;

/**
 * 描述一个列
 */
public class ColumnImpl implements Column {
    @Setter
    @Getter
    protected String tableName;
    @Setter
    @Getter
    protected String columnName;
    @Setter
    @Getter
    protected String alias;
    //
    @Setter
    @Getter
    protected Type type;
    @Setter
    @Getter
    protected boolean autoIncrement;
    @Setter
    @Getter
    protected boolean distinct;
    @Setter
    @Getter
    protected boolean isNot = false;
    @Setter
    @Getter
    protected Long correlateSubQueryItemId = 0L;

    public ColumnImpl() {
    }

    public ColumnImpl(String columnName, String alias, Type type) {
        this.columnName = columnName;
        this.alias = alias;
        this.type = type;
    }

    public ColumnImpl assignment(Parameters parameters) {
        return this;
    }

    public void setType(Type type) {
        this.type = type;

    }

    @Override
    public String getColumnName() {
        return this.columnName;
    }

    @Override
    public void setColumnName(String columnName) {
        this.columnName = columnName;

    }


    /**
     * 当前列名优先比较传入参数item别名然后比较传入参数item列名
     */
    public boolean isSameColumnName(Item item) {
        String columnName = this.getColumnName();
        String columnName2 = item.getColumnName();
        if ($.isNotNullAndNotEmpty(item.getAlias())) {
            columnName2 = item.getAlias();
        }
        return columnName.equals(columnName2);
    }

    public String getFullName() {
        if (this.tableName != null) {
            return tableName + "." + this.getColumnName();
        } else {
            return this.getColumnName();
        }
    }

    @Override
    public void setIsNot(boolean isNot) {
        this.isNot = isNot;

    }


    public Column copy() {
        Column column = ObjectCreateFactory.createColumn();
        column.setColumnName(columnName);
        column.setAlias(alias);
        column.setType(type);
        column.setTableName(tableName);
        column.setDistinct(isDistinct());
        column.setIsNot(isNot);
        column.setAutoIncrement(autoIncrement);
        column.setCorrelateSubQueryItemId(correlateSubQueryItemId);
        return column;
    }

    public int compareTo(Object o) {
        throw new UnsupportedOperationException();
    }

    public void accept(IExecutePlanVisitor executePlanVisitor) {
        executePlanVisitor.visit(this);
    }

    public Long getCorrelateSubQueryItemId() {
        return correlateSubQueryItemId;
    }

    public void setCorrelateSubQueryItemId(Long subQueryCorrelateFilterId) {
        this.correlateSubQueryItemId = subQueryCorrelateFilterId;

    }

    // ================== hashcode/equals/toString不要随意改动=================

    /**
     * 这个方法不要被自动修改！ 在很多地方都有用到。
     */

    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + (distinct ? 1231 : 1237);
        result = prime * result + ((columnName == null) ? 0 : columnName.hashCode());
        result = prime * result + ((tableName == null) ? 0 : tableName.hashCode());
        return result;
    }

    /**
     * 这个方法不要被自动修改！ 在很多地方都有用到。
     */

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }

        ColumnImpl other = (ColumnImpl) obj;
        // setAliasAndSetNeedBuild 都不为空的时候，进行比较，如果不匹配则返回false,其余时候都跳过alias匹配
        if (alias != null && other.alias != null) {
            if (!alias.equals(other.alias)) {
                return false;
            }
        }

        if (columnName == null) {
            if (other.columnName != null)
                return false;
        } else if (!columnName.equals(other.columnName))
            return false;
        if (tableName == null) {
            return other.tableName == null;
        } else
            return tableName.equals(other.tableName);
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        if (this.isDistinct()) {
            sb.append("distinct ");
        }
        if (this.getTableName() != null) {
            sb.append(this.getTableName()).append(".");
        }

        sb.append(this.getColumnName());
        if (this.getAlias() != null) {
            sb.append(" as ").append(this.getAlias());
        }
        return sb.toString();
    }

}
